/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "DXShaderEffect.h"
#include "Texture.h"
#include "core/core.h"
#include "Timer.h"
#include "OSFile.h"
#include "core/core.h"

#pragma warning(disable:4311)
#pragma warning(disable:4312)

namespace directx {

DXShaderEffect::DXShaderEffect(void)
: IShaderEffect(), 
  pDXEffect(NULL),
  hWorld(0),
  hWorldInv(0),
  hWorldIT(0),
  hView(0),
  hViewInv(0),
  hProj(0),
  hViewProj(0),
  hViewProjInv(0),
  hWorldView(0),
  hWorldViewProj(0),
  hWorldViewIT(0),
  hCameraPos(0),
  hTime(0),
  hLight0(0),
  hGlobalWorldTransform(0),
  iRequestedHandles(0),
  iVerifiedHandles(0),
  time(0.0f)
{
	m_mData.clear();
}

DXShaderEffect::~DXShaderEffect(void)
{
	release();
	m_mData.clear();
}

void DXShaderEffect::release()
{
	RELEASE( pDXEffect );
	bIsLoaded = false;
}

void DXShaderEffect::reset()
{
	// Get the d3dDevice -> see DXResource
	DXResource::reset();

	if (bIsLoaded) {
		// Get the d3dDevice -> see DXResource
		load(sFilename);
	}
}

bool DXShaderEffect::load(const std::string &filename)
{
	release();
	sFilename = filename;
	LPD3DXBUFFER pBufferErrors = NULL;
	DWORD flags = 0;
	iVerifiedHandles = 0;	// Set the verified handles to 0

#ifdef _DEBUG
	flags |= D3DXSHADER_DEBUG;
#endif
	
	// Read the file
	OSFile file;
	if (!file.readFile(filename)) {
		coreGetLog()->WriteError("Could not read file " + filename, __FILE__, __LINE__);
		return false;
	}
	UINT len = file.getSize();
	
	DXShaderInclude inc;

	std::string fname = coreGetWorkingDirectory() + filename;

//	if (FAILED( D3DXCreateEffectFromFile(pd3dDevice, fname.c_str(), NULL, NULL, flags, NULL, &pDXEffect, &pBufferErrors)))
	if (FAILED( D3DXCreateEffect(pd3dDevice, file.getData(), len, NULL, &inc, flags, NULL, &pDXEffect, &pBufferErrors)))
	{
		coreGetLog()->WriteError("Loading of DXShaderEffect " + filename + " failed", __FILE__, __LINE__);
		if (pBufferErrors) {
			LPVOID pCompilErrors = pBufferErrors->GetBufferPointer();
			coreGetLog()->WriteError((const char*) pCompilErrors, __FILE__, __LINE__);
		}
		return false;
	}
	RELEASE( pBufferErrors );

	coreGetLog()->WriteLog("Loading DXShaderEffect " + filename + " successful", __FILE__, __LINE__);
	bIsLoaded = true;

	hWorld         = pDXEffect->GetParameterBySemantic(NULL, "WORLD");
	hWorldInv      = pDXEffect->GetParameterBySemantic(NULL, "WORLDINV");
	hWorldIT       = pDXEffect->GetParameterBySemantic(NULL, "WORLDIT");
	hView          = pDXEffect->GetParameterBySemantic(NULL, "VIEW");
	hViewInv       = pDXEffect->GetParameterBySemantic(NULL, "VIEWINV");
	hProj          = pDXEffect->GetParameterBySemantic(NULL, "PROJECTION");
	hViewProj      = pDXEffect->GetParameterBySemantic(NULL, "VIEWPROJECTION");
	hViewProjInv   = pDXEffect->GetParameterBySemantic(NULL, "VIEWPROJECTIONINV");
	hWorldView     = pDXEffect->GetParameterBySemantic(NULL, "WORLDVIEW");
	hWorldViewProj = pDXEffect->GetParameterBySemantic(NULL, "WORLDVIEWPROJECTION");
	hWorldViewIT   = pDXEffect->GetParameterBySemantic(NULL, "WORLDVIEWIT");
	hCameraPos     = pDXEffect->GetParameterBySemantic(NULL, "CAMERAPOSITION");
	hTime          = pDXEffect->GetParameterBySemantic(NULL, "TIME");
	hLight0        = pDXEffect->GetParameterBySemantic(NULL, "LIGHT0");

	hGlobalWorldTransform = pDXEffect->GetParameterBySemantic(NULL, "WORLDGLOBAL");

	checkRegisteredHandles();
	return true;
}

bool DXShaderEffect::bind(bool useBestValidTechnique)
{
	if (s_pGlobalShader != NULL && s_pGlobalShader != this) 
		return false;

	if (!pDXEffect || !bIsLoaded )
	{
		coreGetLog()->WriteWarning("Can't bind DXShaderEffect. No DXShaderEffect file loaded.", __FILE__, __LINE__);
		return false;
	}

	if (FAILED( pDXEffect->Begin(&uiNumPasses, 0) ))
	{
		coreGetLog()->WriteError("Could not bind DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}

	time = static_cast<float>(coreGetTimer()->getTime());

	return true;
}

bool DXShaderEffect::unbind()
{
	if (s_pGlobalShader != NULL && s_pGlobalShader != this) 
		return false;

	if (!pDXEffect || !bIsLoaded)
	{
		coreGetLog()->WriteWarning("Can't unbind DXShaderEffect. No DXShaderEffect file loaded.", __FILE__, __LINE__);
		return false;
	}

	if (FAILED( pDXEffect->End() ))
	{
		coreGetLog()->WriteError("Could not unbind DXShaderEffect", __FILE__, __LINE__);
		return false;
	}

	if (s_pGlobalShader == this) {
		s_pGlobalShader = NULL;
	}

	return true;
}

bool DXShaderEffect::beginPass(int pass)
{
	if (!pDXEffect || !bIsLoaded)
	{
		coreGetLog()->WriteWarning("Can't begin DXShaderEffect pass. No DXShaderEffect file loaded.", __FILE__, __LINE__);
		return false;
	}

	if (FAILED( pDXEffect->BeginPass(pass) ))
	{
		char buff[3];
		memset(buff, 0, sizeof(buff));
		sprintf_s(buff, 3, "%i", pass);
		std::string x(buff);
		coreGetLog()->WriteError("Could not begin DXShaderEffect pass" + x + ": " + sFilename, __FILE__, __LINE__);
		return false;
	}

	return true;
}

bool DXShaderEffect::endPass()
{
	if (!pDXEffect || !bIsLoaded )
	{
		coreGetLog()->WriteWarning("Can't end DXShaderEffect pass. No DXShaderEffect file loaded.", __FILE__, __LINE__);
		return false;
	}

	if (FAILED( pDXEffect->EndPass() ))
	{
		coreGetLog()->WriteError("Could not end DXShaderEffect pass: " + sFilename, __FILE__, __LINE__);
		return false;
	}
	return true;
}

bool DXShaderEffect::setVariables() 
{
	if (!pDXEffect || !bIsLoaded ) {
		coreGetLog()->WriteWarning("Can't set DXShaderEffect variables. No DXShaderEffect file loaded.", __FILE__, __LINE__);
		return false;
	}
	// TODO: See if we still need this. 
	// Set the textures for the technique
	static std::map<D3DXHANDLE, sEffectData>::iterator it;
	for (it = m_mData.begin(); it != m_mData.end(); ++it) 
	{
		if ((it->second).dataType == TYPE_TEXTURE) {
			ITexture *texture = (ITexture*)(it->second).data;
			if ( texture->isVolumeTexture() ) 
			{
				if (FAILED( pDXEffect->SetTexture( it->first, ((Texture*)texture)->getD3DVolumeTexture() ) ))
				{
					coreGetLog()->WriteError("Could not set volume texture for DXShaderEffect " + sFilename, __FILE__, __LINE__);
					return false;
				}
			}
			else 
			{
				if (FAILED( pDXEffect->SetTexture( it->first, ((Texture*)texture)->getD3DTexture() ) ))
				{
					coreGetLog()->WriteError("Could not set texture for DXShaderEffect " + sFilename, __FILE__, __LINE__);
					return false;
				}
			}
		} 
		else if ((it->second).dataType == TYPE_FLOAT) {
			if (FAILED( pDXEffect->SetFloatArray(it->first, (float*)(it->second).data, (it->second).numElements) ))
			{
				coreGetLog()->WriteError("Could not set float array for DXShaderEffect " + sFilename, __FILE__, __LINE__);
				return false;
			}
		}
		else if ((it->second).dataType == TYPE_INT) {
			if (FAILED( pDXEffect->SetIntArray(it->first, (int*)(it->second).data, (it->second).numElements) ))
			{
				coreGetLog()->WriteError("Could not set int array for DXShaderEffect " + sFilename, __FILE__, __LINE__);
				return false;
			}
		}
		else if ((it->second).dataType == TYPE_BOOL) {
			BOOL* winBools = new BOOL[(it->second).numElements];
			for (unsigned int i=0; i<(it->second).numElements; ++i) winBools[i] = (BOOL) ((bool*)(it->second).data)[i];
			if (FAILED( pDXEffect->SetBoolArray(it->first, winBools , (it->second).numElements) ))
			{
				coreGetLog()->WriteError("Could not set int array for DXShaderEffect " + sFilename, __FILE__, __LINE__);
				return false;
			}
			DELETE_POINTER(winBools);
		}
		else if ((it->second).dataType == TYPE_MATRIX) {
			math::Matrix4 *matrix = (math::Matrix4*)(it->second).data;
			D3DXMATRIX mat(&matrix->m[0]);
			if (FAILED( pDXEffect->SetMatrix(it->first, &mat) ))
			{
				coreGetLog()->WriteError("Could not set matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
				return false;
			}
		}
	} // END for

	static D3DXMATRIX mat, tmpMat;
	if (hWorld) {
		mat = &(pRenderer->getWorldMatrix().m[0]);
		if (FAILED( pDXEffect->SetMatrix(hWorld, &mat) ))
		{
			coreGetLog()->WriteError("Could not set WORLD matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hWorldInv) {
		tmpMat = &(pRenderer->getWorldMatrix().m[0]);
		D3DXMatrixInverse(&mat, 0, &tmpMat);
		if (FAILED( pDXEffect->SetMatrix(hWorldInv, &mat) ))
		{
			coreGetLog()->WriteError("Could not set WORLDINV matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hWorldIT) {
		tmpMat = &(pRenderer->getWorldMatrix().m[0]);
		D3DXMatrixInverse(&mat, 0, &tmpMat);
		D3DXMatrixTranspose(&tmpMat, &mat);
		if (FAILED( pDXEffect->SetMatrix(hWorldIT, &tmpMat) ))
		{
			coreGetLog()->WriteError("Could not set WORLDIT matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hView) {
		mat = &(pRenderer->getViewMatrix().m[0]);
		if (FAILED( pDXEffect->SetMatrix(hView, &mat) ))
		{
			coreGetLog()->WriteError("Could not set VIEW matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hViewInv) {
		tmpMat = &(pRenderer->getViewMatrix().m[0]);
		D3DXMatrixInverse(&mat, 0, &tmpMat);
		if (FAILED( pDXEffect->SetMatrix(hViewInv, &mat) ))
		{
			coreGetLog()->WriteError("Could not set VIEWINV matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hProj) {
		mat = &(pRenderer->getProjMatrix().m[0]);
		if (FAILED( pDXEffect->SetMatrix(hProj, &mat) ))
		{
			coreGetLog()->WriteError("Could not set PROJECTION matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hViewProj) {
		mat = &(pRenderer->getViewProjMatrix().m[0]);
		if (FAILED( pDXEffect->SetMatrix(hViewProj, &mat) ))
		{
			coreGetLog()->WriteError("Could not set VIEWPROJECTION matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hViewProjInv) {
		tmpMat = &(pRenderer->getViewProjMatrix().m[0]);
		D3DXMatrixInverse(&mat, 0, &tmpMat);
		if (FAILED( pDXEffect->SetMatrix(hViewProjInv, &mat) ))
		{
			coreGetLog()->WriteError("Could not set VIEWPROJECTIONINV matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hWorldView) {
		mat = &(pRenderer->getWorldViewMatrix().m[0]);
		if (FAILED( pDXEffect->SetMatrix(hWorldView, &mat) ))
		{
			coreGetLog()->WriteError("Could not set WORLDVIEW matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hWorldViewProj) {
		mat = &(pRenderer->getWorldViewProjMatrix().m[0]);
		if (FAILED( pDXEffect->SetMatrix(hWorldViewProj, &mat) ))
		{
			coreGetLog()->WriteError("Could not set WORLDVIEWPROJECTION matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}	
	if (hWorldViewIT) {
		math::Matrix4 matrix = pRenderer->getWorldViewMatrix();
		matrix.inv();
		mat = &(matrix.m[0]);
		if (FAILED( pDXEffect->SetMatrix(hWorldViewIT, &mat) ))
		{
			coreGetLog()->WriteError("Could not set WORLDVIEWIT matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hCameraPos) {
		math::Vector3 pos = pRenderer->getCamera()->getPosition();
		if (FAILED( pDXEffect->SetFloatArray(hCameraPos, &pos.x, 3) ))
		{
			coreGetLog()->WriteError("Could not set CAMERAPOSITION float3 in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}
	if (hTime) {
		// The current time is set during bind()
		if (FAILED( pDXEffect->SetFloatArray(hTime, &time, 1) ))
		{
			coreGetLog()->WriteError("Could not set TIME float in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}		
	}

	static ILight* light = NULL;
	if (hLight0) {
		static std::list<ILight*>* lights= coreGetScene()->getLights();
		// Get the first light from the list
		if (lights->size() != 0)
			light =	coreGetScene()->getLight(0);

		// The current time is set during bind()
		if (FAILED( pDXEffect->SetValue(hLight0, &light->getShaderLight(), sizeof(sShaderLight)) ))
		{
			coreGetLog()->WriteError("Could not set TIME float in DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}		

	}

	if (FAILED( pDXEffect->CommitChanges() ))
	{
		coreGetLog()->WriteError("Could not commit changes for shader " + sFilename, __FILE__, __LINE__);
		return false;
	}

	return true;
}

bool DXShaderEffect::setTechnique(const std::string &technique)
{
	if (!pDXEffect || !bIsLoaded) return false;

	if (FAILED( pDXEffect->SetTechnique( technique.c_str() ) ))
	{
		coreGetLog()->WriteError("Could not set technique " + technique + " in DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}
	return true;
}

bool DXShaderEffect::setTechnique(const SHADERHANDLE &handle)
{
	if (!pDXEffect || !bIsLoaded) return false;

	if (FAILED( pDXEffect->SetTechnique( (D3DXHANDLE) handle ) ))
	{
		coreGetLog()->WriteError("Could not set technique in DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}
	return true;
}

bool DXShaderEffect::setInt(const SHADERHANDLE &handle, int* ints, int size)
{
	if (!pDXEffect || !bIsLoaded) return false;

	if (FAILED( pDXEffect->SetIntArray((D3DXHANDLE) handle, ints, size) ))
	{
		coreGetLog()->WriteError("Could not set int array in DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}
	return true;
}

bool DXShaderEffect::setBoolean(const SHADERHANDLE &handle, const bool* bools, int size)
{
	if (!pDXEffect || !bIsLoaded) return false;

	BOOL *winBools = new BOOL[size];
	for (int i=0; i<size; ++i) winBools[i] = (BOOL) bools[i];

	if (FAILED( pDXEffect->SetBoolArray((D3DXHANDLE) handle, winBools, size) ))
	{
		coreGetLog()->WriteError("Could not set bool array in DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}

	delete[] winBools;
	return true;
}

bool DXShaderEffect::setFloat(SHADERHANDLE &handle, float* floats, int size)
{
	if (!pDXEffect || !bIsLoaded) return false;

	if (iVerifiedHandles < iRequestedHandles) 
		handle = recheckHandle(handle);

	if (FAILED( pDXEffect->SetFloatArray((D3DXHANDLE) handle, floats, size) ))
	{
		coreGetLog()->WriteError("Could not set float array in DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}
	return true;
}

bool DXShaderEffect::setMatrix(const SHADERHANDLE &handle, math::Matrix4 *matrix)
{
	static D3DXMATRIX *mat;
	if (!pDXEffect || !bIsLoaded) return false;

	mat = (D3DXMATRIX *)&matrix->m[0];
	if (FAILED( pDXEffect->SetMatrix((D3DXHANDLE) handle, mat) ))
	{
		coreGetLog()->WriteError("Could not set matrix in DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}
	return true;
}

bool DXShaderEffect::setGlobalWorldTransformMatrix(math::Matrix4 *matrix)
{
	static D3DXMATRIX *mat;
	if (!pDXEffect || !hGlobalWorldTransform || !bIsLoaded) return false;

	mat = (D3DXMATRIX *)&matrix->m[0];
	if (FAILED( pDXEffect->SetMatrix(hGlobalWorldTransform, mat) ))
	{
		coreGetLog()->WriteError("Could not set world transform matrix for global shader in DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}
	setVariables();
	return true;
}

bool DXShaderEffect::setTexture(const SHADERHANDLE &handle, ITexture *texture)
{
	if (!pDXEffect || !bIsLoaded) return false;
	
	if (!texture) {
		pDXEffect->SetTexture( (D3DXHANDLE) handle, NULL);
		return true;
	}
	if ( texture->isVolumeTexture() ) {
		if (FAILED( pDXEffect->SetTexture( (D3DXHANDLE) handle, ((Texture*)texture)->getD3DVolumeTexture() ) ))
		{
			coreGetLog()->WriteError("Could not set volume texture for DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	} else {
		if (FAILED( pDXEffect->SetTexture( (D3DXHANDLE) handle, ((Texture*)texture)->getD3DTexture() ) ))
		{
			coreGetLog()->WriteError("Could not set texture for DXShaderEffect " + sFilename, __FILE__, __LINE__);
			return false;
		}
	}

	return true;
}

bool DXShaderEffect::setData(const SHADERHANDLE &handle, void* data, int numBytes)
{
	if (!pDXEffect || !bIsLoaded) return false;

	if (FAILED( pDXEffect->SetValue( (D3DXHANDLE) handle, data, numBytes ) ))
	{
		coreGetLog()->WriteError("Could not set data for DXShaderEffect " + sFilename, __FILE__, __LINE__);
		return false;
	}
	return true;
}

bool DXShaderEffect::addTexture(const SHADERHANDLE &handle, ITexture* texture)
{
	D3DXHANDLE h = NULL;
	sEffectData data;
	data.dataType = TYPE_TEXTURE;
	data.numElements = 1;
	data.data = texture;
	h = (D3DXHANDLE) handle;
	m_mData[h] =  data;
	return true;
}

bool DXShaderEffect::hasParameter(const std::string &identifier)
{
	if (!pDXEffect || !bIsLoaded) return false;

	D3DXHANDLE h = 0;
	h = pDXEffect->GetParameterByName(NULL, identifier.c_str());
	if (h) return true;
	return false;
}

SHADERHANDLE DXShaderEffect::getParameterBySemantic(const std::string &semantic) 
{
	if (!pDXEffect || !bIsLoaded) return 0;

	D3DXHANDLE handle = pDXEffect->GetParameterBySemantic(NULL, semantic.c_str());

	if (!handle)	return 0;
	else {
		orignames[(SHADERHANDLE)handle] = semantic;
		++iVerifiedHandles;
		return (SHADERHANDLE)handle;
	}
}

int* DXShaderEffect::getParameterValueAsIntArray(const std::string &identifier, int count)
{
	if (!pDXEffect || !bIsLoaded) return NULL;
	
	int *retval = new int[count];
	D3DXHANDLE h = 0;
	h = pDXEffect->GetParameterByName(NULL, identifier.c_str());
	if (h) {
		pDXEffect->GetIntArray(h, retval, count);
		return retval;
	}
	return NULL;
}

float* DXShaderEffect::getParameterValueAsFloatArray(const std::string &identifier, int count)
{
	if (!pDXEffect || !bIsLoaded) return NULL;

	float *retval = new float[count];
	D3DXHANDLE h = 0;
	h = pDXEffect->GetParameterByName(NULL, identifier.c_str());
	if (h) {
		pDXEffect->GetFloatArray(h, retval, count);
		return retval;
	}
	return NULL;
}

SHADERHANDLE DXShaderEffect::getParameterByName(const std::string &identifier)
{
	if (!pDXEffect || !bIsLoaded) return 0;

	D3DXHANDLE handle = pDXEffect->GetParameterByName(NULL, identifier.c_str());

	if (!handle)
		handle = pDXEffect->GetTechniqueByName(identifier.c_str());			
	
	if (!handle) 
		return 0;
	else {
		orignames[(SHADERHANDLE)handle] = identifier;
		++iVerifiedHandles;
		++iRequestedHandles;
		return (SHADERHANDLE)handle;
	}
}

SHADERHANDLE DXShaderEffect::recheckHandle(const SHADERHANDLE &handle)
{
	++iVerifiedHandles;
	return getParameterByName(orignames[handle]);
}

bool DXShaderEffect::beginParameterBlock()
{
	if (FAILED( pDXEffect->BeginParameterBlock())) {
		coreGetLog()->WriteError("Could not begin a new Parameter block. Calling endParameterBlock() will not return a valid block handle.", __FILE__, __LINE__);
		return false;
	} 
	return true;
}

SHADERHANDLE DXShaderEffect::endParameterBlock()
{
	D3DXHANDLE handle = pDXEffect->EndParameterBlock();
	return (SHADERHANDLE) handle;
}

void DXShaderEffect::applyParameterBlock(SHADERHANDLE blockHandle)
{
	pDXEffect->ApplyParameterBlock( (D3DXHANDLE) blockHandle);
}


HRESULT DXShaderInclude::Open(D3DXINCLUDE_TYPE IncludeType, LPCSTR pName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes)
{
	file = new OSFile();

	if (file->readFile(std::string(pName))) {
		*ppData = file->getData();
		*pBytes = file->getSize();
	} else {
		coreGetLog()->WriteError("Could not open fx file for reading", __FILE__, __LINE__);
		return E_FAIL;
	}
	// Read the data

    return S_OK;
}

//------------------------------------------------------------------------------
/**
*/
HRESULT DXShaderInclude::Close(LPCVOID pData)
{
    DELETE_POINTER(file);
    return S_OK;
}


} // namespace

#pragma warning(default:4311)
#pragma warning(default:4312)
